PCM转换成WAV

您所在的位置:网站首页 Microsoft store下不了微信 PCM转换成WAV

PCM转换成WAV

2023-09-08 20:50| 来源: 网络整理| 查看: 265

1 音频格式简介

AudioRecord录制的音频文件格式为PCM,MediaPlayer无法播放PCM格式文件,AudioTrack可以播放PCM格式文件。 PCM(Puls Code Modulation)全称脉码调制录音,PCM录音就是将声音的模拟信号表示成0,1标识的数字信号,未经任何编码和压缩处理,所以可以认为PCM是未经压缩的音频原始格式。PCM格式文件中不包含头部信息,播放器无法知道采样率,声道数,采样位数,音频数据大小等信息,导致无法播放。

PCM格式缺少头部信息,支持的播放器有限,所以一般需要把PCM格式转换成其他格式文件。

WAV是一种符合 RIFF Resource Interchange File Format规范的微软开发的音频格式,是一种无损格式。WAV对音频流的编码没有硬性规定,除了PCM之外,还有几乎所有支持ACM规范的编码都可以为WAV的音频流进行编码(类似mp3),只需要在被编码音频的前面添加带有音频流的编码参数的WAV的文件头。WAV格式支持许多压缩算法,支持多种音频位数、采样频率和声道,采用44.1kHz的采样频率,16位量化位数,因此WAV的音质与CD相差无几,但WAV格式对存储空间需求太大不便于交流和传播。

MP3利用MPEG Audio Layer3 压缩方式进行压缩,所以简称为MP3,是一种有损压缩格式。 MPEG Audio Layer 3 压缩技术可以将音乐以1:10 甚至 1:12 的压缩率,能够在音质丢失很小的情况下把文件压缩到更小的程度。由于MP3体积小,音质高互联网上音乐几乎都是这种格式。但Mp3最高比特率320K,高频部分一刀切是他的缺点,对音质要求高的话还是建议wav格式。

ARM格式全称Adaptive Multi-Rate 和 Adaptive Multi-Rate Wideband,主要用于移动设备的音频,压缩比比较大,但相对其他的压缩格式质量比较差,多用于人声,通话,是一种有损压缩格式。

Ogg全称应该是OGG Vobis(ogg Vorbis) 是一种新的音频压缩格式,类似于MP3等现有的音乐格式。相对于MP3压缩技术它是完全免费、开放和没有专利限制的,是一种有损压缩格式。

AAC(Advanced Audio Coding),中文称为“高级音频编码”,出现于1997年,基于 MPEG-2的音频编码技术,是一种有损压缩技术。

LAC即是Free Lossless Audio Codec的缩写,为无损音频压缩编码,由于不会丢失任何音频信息可以利用算法恢复原始编码,前景广阔。

2 WAV文件头信息

WAV格式全称为WAVE,前面提到只需要在PCM文件的前面添加WAV文件头,就可以生成WAV格式文件,下面说一说WAV文件头格式。 WAV符合 RIFF Resource Interchange File Format规范,RIFF文件结构可以看作是树状结构,其基本构成是称为"块"(Chunk)的单元,WAVE文件是由若干个Chunk组成的。WAV文件本身由三个“块”信息组成:将文件标识为WAV文件的RIFF块,识别采样率等参数的FORMAT块和包含实际数据(样本)的DATA块。

简而言之,什么是 PCM? 在数字域中,PCM(Pulse Code Modulation)是最简单的机制来存储音频。根据Nyquest定理对模拟音频进行采样,并以二进制格式顺序存储各个样本。

波形文件是最常用的存储 PCM 数据的格式。但是,在您深入研究波形文件的内部结构之前,了解构成波形文件格式基础的交换格式文件会有所帮助。

Interchange Format Files (IFF) 交换格式文件 它是由一家名为Electronic Arts的公司开发的“ Meta ”文件格式。这种格式的全称是ElectronicArts Interchange File Format 1985 (EA IFF 85)。IFF 为 IFF 兼容文件的结构制定了顶级协议。它针对诸如版本控制、兼容性、可移植性等问题。它有助于指定与特定产品无关的标准化文件格式。

出于解释波形文件的目的,可以推测波形文件格式基于通用 IFF 格式。如果您有兴趣深入了解 IFF,这里有一个很棒的链接:http://www.dcs.ed.ac.uk/home/mxr/gfx/2d/IFF.txt。

WAVE 文件格式 该WAVE文件格式支持多种位分辨率,采样率和音频通道。我想说这是在 PC 上存储 PCM 音频的最流行的格式,并且已经成为术语“raw digital audio”的同义词。

WAVE 文件格式基于Microsoft 版本的 Electronic Arts Interchange File Format方法,用于存储数据。与IFF的格言保持一致,Wave 文件中的数据存储在许多不同的“chunks”中。因此,如果供应商想要在 Wave 文件中存储附加信息,他只需将信息添加到新块中,而不是尝试调整基本文件格式或提出自己的专有文件格式。这是IFF的主要目标。

如前所述,WAVE 文件是许多不同类型块的集合。但是,有效的波形文件中需要存在三个块:

1. ‘RIFF’, ‘WAVE’ chunk 2. “fmt” chunk 3. ‘data’ chunk

所有其他块都是可选的。Riff chunk 波形块是标识符块,它告诉我们这是一个波形文件。fmt chunk 包含描述波形的重要参数,例如其采样率、每个样本的位数等。data chunk 包含实际的波形数据。

使用 WAVE 文件的应用程序必须能够读取三个必需的块,尽管它可以忽略可选的块。但是,所有对 wave 文件执行复制操作的应用程序都应该复制 WAVE 中的所有块。

Riff chunk始终是第一大块。fmt chunk 应该是data chunk之前存在。除此之外,WAVE 文件中块的顺序没有限制。

以下是最小 WAVE 文件的布局示例。它由包含三个所需块的单个 WAVE 组成。 在这里插入图片描述

所有的WAV都有一个文件头,这个文件头记录着音频流的编码参数。数据块的记录方式是little-endian字节顺序。

C语言中对应的WAV的文件头结构如下:

// RIFF chunk struct RIFF_HEADER { TCHAR szRiffID[4]; // 'R','I','F','F' DWORD dwRiffSize; TCHAR szRiffFormat[4]; // 'W','A','V','E' }; // fmt chunk struct WAVE_FORMAT { WORD wFormatTag; WORD wChannels; DWORD dwSamplesPerSec; DWORD dwAvgBytesPerSec; WORD wBlockAlign; WORD wBitsPerSample; }; struct FMT_BLOCK { TCHAR szFmtID[4]; // 'f','m','t',' ' please note the // space character at the fourth location. DWORD dwFmtSize; WAVE_FORMAT wavFormat; }; // data chunk struct DATA_BLOCK { TCHAR szDataID[4]; // 'd','a','t','a' DWORD dwDataSize; };

C语言里面的字WORD(32位),16进制文件对应2个字节(Byte),而DWORD(64位),对应4个字节。16进制文件的存储规律,对于WORD,先存储低位字节,然后存储高位字节,而DWORD,则先存储低两位的低位,然后是低两位的高位,然后是高两位的低位,然后是高两位的高位。所以看下图时要对照WORD和DWORD格式的存储结构。 WAVE文件结构: WAVE file format WAVE文件头分量: 在这里插入图片描述

WAV文件头信息由44个字节组成,所以只需要在PCM文件头部添加44个字节的WAV文件头,就可以生成WAV格式文件。

// 节选 C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Include\mmsystem.h 部分代码 #ifndef WAVE_FORMAT_PCM /* OLD general waveform format structure (information common to all formats) */ typedef struct waveformat_tag { WORD wFormatTag; /* format type */ WORD nChannels; /* number of channels (i.e. mono, stereo, etc.) */ DWORD nSamplesPerSec; /* sample rate */ DWORD nAvgBytesPerSec; /* for buffer estimation */ WORD nBlockAlign; /* block size of data */ } WAVEFORMAT, *PWAVEFORMAT, NEAR *NPWAVEFORMAT, FAR *LPWAVEFORMAT; /* flags for wFormatTag field of WAVEFORMAT */ #define WAVE_FORMAT_PCM 1 /* specific waveform format structure for PCM data */ typedef struct pcmwaveformat_tag { WAVEFORMAT wf; WORD wBitsPerSample; } PCMWAVEFORMAT, *PPCMWAVEFORMAT, NEAR *NPPCMWAVEFORMAT, FAR *LPPCMWAVEFORMAT; #endif /* WAVE_FORMAT_PCM */ ChunkID:大小为4个字节数据,内容为“RIFF”,表示资源交换文件标识ChunkSize:大小为4个字节数据,内容为一个整数,表示从下个地址开始到文件尾的总字节数:RIFF-chunk 中的 分量:ChunkSize = WAV文件大小 - 8Format:大小为4个字节数据,内容为“WAVE”,表示WAV文件标识Subchunk1 ID:大小为4个字节数据,内容为“fmt ”,表示波形格式标识(fmt ),最后一位空格。Subchunk1 Size:大小为4个字节数据,内容为一个整数,表示从下个地址开始到本chunk尾的总字节数,也表示结构体PCMWAVEFORMAT的长度 16 字节。AudioFormat:大小为2个字节数据,内容为一个短整数,表示格式种类(值为1时,表示数据为线性PCM编码)NumChannels:大小为2个字节数据,内容为一个短整数,表示通道数,单声道为1,双声道为2SampleRate:大小为4个字节数据,内容为一个整数,表示采样率,比如44100ByteRate:大小为4个字节数据,内容为一个整数,表示波形数据传输速率(每秒平均字节数),大小为 采样率 * 通道数 * 采样位数BlockAlign:大小为2字节数据,内容为一个短整数,表示DATA数据块长度,大小为 通道数 * 采样位数BitsPerSample:大小为2个字节数据,内容为一个短整数,表示采样位数,即PCM位宽,通常为8位或16bitSubchunk2 ID:大小为4个字节数据,内容为“data”,表示数据标记符Subchunk2 Size:大小为4个字节数据,内容为一个整数,表示接下来声音数据的总大小,需要减去头部的44个字节。:data-chunk 中的 分量:Subchunk2Size = WAV文件大小 - 44data:就是其他编码文件内容

WAV文件实例: 在这里插入图片描述 上图中红色部分共44个字节,表示正式WAV文件头结构,下面是该文件头各分量说明:

ChunkID: “52 49 46 46 ”对应ASCII中的RIFF,固定格式。ChunkSize: “94 71 07 00” 表示WAV文件总大小 - 8byte,不包括文件头8个字节。“94 71 07 00” 对应的正序16进制为“00077194”大小为487828,可以推算出WAV文件总大小为487836(正好与图片中字节总数一致).Format:“57 41 56 45 ”:表示ASCII编码的WAVE,固定写法。Subchunkl ID:”66 6D 74 20”表示ASCII编码的fmt,固定写法。(‘f’ ‘m’ ‘t’ ’ ’ , 4个字符中的最后一个字符是 空格字符)Subchunkl Size:“10 00 00 00 ”DWORD格式,对应16。(这个也应该是固定值 16)AudioFormat:“01 00”WORD格式,对应定义为编码格式“WAVE_FORMAT_PCM”。NumChannels:“01 00”WORD格式,对应数字1,表示声道数为1,这是个单声道Wav。SampleRate:”00 7D 00 00”,DWORD格式,对应16进制大小为“00007D00”采样率为32000.ByteRate:”00 FA 00 00”,DWORD格式,大小为传输速率为64000.BlockAlign:02 00,WORD格式,对应2BitsPerSample:10 00 ,对应WAVE文件的采样大小,数值为16,采样大小为16BitsSubchunk2 ID:“64 61 74 61”表示为ASCII的data,开始数据区。Subchunk2 Size:“70 71 07 00”格式为DWORD,大小为487792,推算出WAV文件总大小=487792+44=487836.

文件头三个chunk中,有两个分量可以间接表示文件总大小:ChunkSize、Subchunk2 Size 如果二者出现错误,会不会影响WAV文件的播放呢? 下面以上面的实例为基础,分别列出:正常不修改、只修改ChunkSize、只修改Subchunk2 Size,三种情形下的WAV文件状态信息。

正常不修改时: 此时WAV文件播放正常,文件信息用mediainfo分析如下: 在这里插入图片描述只修改ChunkSize时:将其内容“94 71 07 00”修改成“94 71 00 00”后 WAV文件播放正常,文件信息如下: 在这里插入图片描述只修改Subchunk2 Size时:将其内容“70 71 07 00”修改成“70 71 00 00” 文件播放时 总时长异常,文件信息如下: 在这里插入图片描述 在上面三种情形下,只有当 Subchunk2 Size 变更时,才会出现文件异常,主要体现在播放总时长上。 由此可知,WAV文件的播放时长是由 Subchunk2 Size 决定的。 3 PCM转WAV格式

主要采样频率和AudioFormat和声道数,如果pcm转wav过程中,这些信息和录音时的设置不同,会导致生成的wav文件都是杂音,所以抽取成了需要外部传入。 PCM转换WAV分两步完成:

先open一个新的WAV文件,在文件开始处依次写入三个chunk:RIFF-chunk、fmt-chunk、data-chunk。这三个chunk构成WAV文件头。在WAV文件头后直接写入PCM数据即可。

PS:其实 data-chunk 包含 8字节chunk头 、PCM数据 两部分,我们WAV文件头中的data-chunk部分只需要8字节chunk头就行。

参考: [1] https://blog.csdn.net/u010126792/article/details/86493494 [2] https://www.codeguru.com/cpp/g-m/multimedia/audio/article.php/c8935/PCM-Audio-and-Wave-Files.htm#page-1 [3] https://blog.csdn.net/vacu_um/article/details/70195761



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3